package autosession

import (
	"context"
	"net/http"
)

type CookieOption struct {
	Path     string
	Domain   string
	MaxAge   int
	Secure   bool
	HttpOnly bool
	SameSite http.SameSite
}

type cookieInspector struct {
	encryptor    InspectorEncryptor
	cookieOption CookieOption
}

func NewCookieInspector(option CookieOption) Inspector {
	return NewCookieInspectorWith(option, &JwtEncryptor{})
}

func NewCookieInspectorWith(option CookieOption, enc InspectorEncryptor) Inspector {
	return cookieInspector{
		encryptor:    enc,
		cookieOption: option,
	}
}

func (i cookieInspector) SignId(ctx context.Context, sessionId string, options *Options) (string, error) {
	return i.encryptor.Sign(sessionId, options)
}

func (i cookieInspector) Read(ctx context.Context, req *http.Request, name string) (sessionId string, err error) {
	// 从 cookie里读取
	cookie, err := req.Cookie(name)
	if err != nil || cookie.Value == "" {
		return "", &NotFoundError{"cookie中未读取到" + name}
	}
	return i.encryptor.Parse(cookie.Value)
}

func (i cookieInspector) Write(ctx context.Context, name, sessionId string, options *Options, writter WritterFunc) (string, error) {
	signedString, err := i.encryptor.Sign(sessionId, options)
	if err != nil {
		return "", err
	}

	cookie := &http.Cookie{
		Name:     name,
		Value:    signedString,
		Path:     i.cookieOption.Path,
		Domain:   i.cookieOption.Domain,
		MaxAge:   i.cookieOption.MaxAge,
		Secure:   i.cookieOption.Secure,
		HttpOnly: i.cookieOption.HttpOnly,
		SameSite: i.cookieOption.SameSite,
	}
	err = writter(ctx, "Set-Cookie", cookie.String())
	if err != nil {
		return "", err
	}
	return signedString, nil
}
